﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Linq;

namespace PachubeDataAccess.Models
{
    public class Feed
    {
        public string ApiKey;

        public int Id { get; set; }
        public string Url { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string LastTimeUpdated { get; set; }
        public string Status { get; set; }

        public FeedLocation Location { get; set; }
        public IEnumerable<DataStream> DataStreams { get; set; }

        public event UpdatedHandler Updated;
        
        public Feed(string apiKey)
        {
            this.ApiKey = apiKey;
        }

        public void Refresh()
        {
            if (!String.IsNullOrWhiteSpace(this.Url))
            { 
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(this.Url  + "?duration=1day");
                req.Method = "GET";
                //req.ContentType = "application/json";
                //req.UserAgent = "NetduinoPlus";
                req.Headers["X-PachubeApiKey"] = ApiKey;

                try
                {
                    req.BeginGetResponse(state =>
                    {
                        try
                        {
                            WebResponse resp = (state.AsyncState as HttpWebRequest).EndGetResponse(state);
                            using (Stream s = resp.GetResponseStream())
                            {
                                byte[] data = new byte[s.Length];
                                s.Read(data, 0, (int)s.Length);
                                string resultAsString = new string(System.Text.Encoding.UTF8.GetChars(data));
                                JObject resultAsJson = JObject.Parse(resultAsString);
                                this.Id = (int)resultAsJson["id"];
                                this.Title = (string)resultAsJson["title"];
                                this.Url = (string)resultAsJson["feed"];
                                this.Status = (string)resultAsJson["status"];
                                this.LastTimeUpdated = (string)resultAsJson["updated"];
                                var desc = (string)resultAsJson["description"];
                                this.Description = String.IsNullOrWhiteSpace(desc) ? "no description" : desc ;
                                this.Location = new FeedLocation();
                                try
                                {
                                    this.Location.Latitude = (double)resultAsJson["location"]["lat"];
                                    this.Location.Longitude = (double)resultAsJson["location"]["lon"];
                                    this.Location.Name = (string)resultAsJson["location"]["name"];
                                    this.Location.Domain = (string)resultAsJson["location"]["domain"];
                                    this.Location.Elevation = (string)resultAsJson["location"]["ele"];
                                    this.Location.IsFixed = ((string)resultAsJson["location"]["disposition"] == "fixed");
                                    this.Location.IsIndoor = ((string)resultAsJson["location"]["exposure"] == "fixed");
                                }
                                catch (Exception)
                                {
                                    Debug.WriteLine("Feed.cs: problem deserializing location");
                                }

                                JToken datastreamsAsJson = resultAsJson.SelectToken("datastreams");
                                this.DataStreams = DataStream.ParseJSON(this, datastreamsAsJson);
                                foreach (var ds in DataStreams)
                                    ds.Refresh();

                                if (Updated != null)
                                {
                                    Updated(this, new FeedUpdatedEventArgs() { Feed = this });
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine("Error in Feed.cs : Refresh(): " + ex.Message + " (" + req.RequestUri.ToString() + ")");
                        }
                    }, req);


                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                }
            }
        }

        public delegate void UpdatedHandler(object sender, FeedUpdatedEventArgs e);
        public class FeedUpdatedEventArgs : EventArgs
        {
            public Feed Feed;
        }

    }

}
